package com.gopay.scheduler.shedulerx.alarm;

import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.gopay.scheduler.shedulerx.event.JobEvent;
import com.gopay.scheduler.shedulerx.event.JobEventBus;
import com.gopay.scheduler.shedulerx.util.ThreadPoolUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AlarmEventBus {
    private final static Logger LOGGER = LoggerFactory.getLogger(AlarmEventBus.class);

    private final EventBus eventBus;

    private static volatile boolean isRegistered = false;

    public static volatile AlarmEventBus alarmEventBus;

    private static final ThreadPoolExecutor busPool = new ThreadPoolExecutor(1, 1, 10, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(100),
            new ThreadFactory() {
                int index = 0;
                @Override
                public Thread newThread(Runnable runnable) {
                    ++this.index;
                    return new Thread(runnable, "gopay-alarm-thread-" + this.index);
                }
            });

    private AlarmEventBus(EventBus eventBus) {
        this.eventBus = eventBus;
        register();
    }

    public static AlarmEventBus getSingle(){
        if(alarmEventBus == null){
            synchronized (JobEventBus.class){
                if(alarmEventBus == null){
                    alarmEventBus =  new AlarmEventBus(new AsyncEventBus(busPool));
                }
            }
        }
        return alarmEventBus;
    }

    private void register() {
        eventBus.register(AlarmEventListener.getSingle());
        isRegistered = true;
    }


    public void alarm(final JobEvent event) {
        if (isRegistered && !busPool.isShutdown()) {
            eventBus.post(event);
        }
    }

    public void shutdown(){
        String poolName = String.format("from class {%s} , and poolName is {%s}",this.getClass().getName(),"作业报警事件线程池");
        ThreadPoolUtil.shutdownGracefully(poolName,busPool,TimeUnit.MINUTES,1);
    }
}
